#include "stdafx.h"
#include "RoomMessage.h"

namespace RoomFW {

RoomMessage::RoomMessage(PortIndex portIndex,
						 MessageID messageID,
						 IPayloadSP payload,
						 const char* senderName,
						 IEndPointSP replyEndpoint,
						 int replyId) : 
	portIndex_(portIndex),
	messageID_(messageID),
	payload_(payload),
	senderName_(senderName),
	replyEndpoint_(replyEndpoint),
	replyId_(replyId)
{
	sig = Q_ROOM_SIG;
}

PortIndex RoomMessage::portIndex() const
{
	return portIndex_;
}

MessageID RoomMessage::messageID() const
{
	return messageID_;
}

IPayloadSP RoomMessage::payload() const
{
	return payload_;
}

IPayloadSP RoomMessage::releasePayload()
{
	return IPayload::ReleaseOwnership(payload_);
}

bool RoomMessage::reply(MessageID messageID, IPayloadSP payload) const
{
	bool retVal = false;

	// Reply to a reply is a design error, hence the assertion.
	ASSERT(0 != replyEndpoint_);
	if (0 == replyEndpoint_)
	{
		throw SendMessageError(
				portIndex_,
				messageID,
				payload,
				SendMessageError::SMER_REPLY_TO_REPLY);
	}
	// Send the reply.
	SendMessageError::Reason reason =
		replyEndpoint_->acceptMessage(messageID, payload, "REPLY");

	// Check for errors.  The InvokeEndpoint will return SMER_INVOKE_TIMEOUT
	// if the caller is no longer waiting.
	switch (reason)
	{
		case SendMessageError::SMER_NONE:
			retVal = true;
			break;
		case SendMessageError::SMER_INVOKE_TIMEOUT:
			retVal = false; // Just to be sure.
			break;
		default:
			throw SendMessageError(
					portIndex_,
					messageID,
					payload,
					reason);
	}
	return retVal;
}

IEndPointSP RoomMessage::replyEndpoint() const
{
	return replyEndpoint_;
}

int RoomMessage::replyId() const
{
	return replyId_;
}

const char* RoomMessage::senderName() const
{
	return senderName_.c_str();
}

}
